home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 023 / ver30 / main.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  6KB  |  290 lines

  1. /*
  2.  * Name:    MicroEMACS
  3.  *        Mainline, macro commands.
  4.  * Version:    29
  5.  * Last edit:    05-Feb-86
  6.  * By:        rex::conroy
  7.  *        decvax!decwrl!dec-rhea!dec-rex!conroy
  8.  */
  9. #include    "def.h"
  10.  
  11. int    thisflag;            /* Flags, this command        */
  12. int    lastflag;            /* Flags, last command        */
  13. int    curgoal;            /* Goal column            */
  14. BUFFER    *curbp;                /* Current buffer        */
  15. WINDOW    *curwp;                /* Current window        */
  16. BUFFER    *bheadp;            /* BUFFER listhead        */
  17. WINDOW    *wheadp;            /* WINDOW listhead        */
  18. BUFFER    *blistp;            /* Buffer list BUFFER        */
  19. short    kbdm[NKBDM] = {(KCTLX|')')};    /* Macro            */
  20. short    *kbdmip;            /* Input  for above        */
  21. short    *kbdmop;            /* Output for above        */
  22. char    pat[NPAT];            /* Pattern            */
  23. SYMBOL    *symbol[NSHASH];        /* Symbol table listhead.    */
  24. SYMBOL    *binding[NKEYS];        /* Key bindings.        */
  25.  
  26. main(argc, argv)
  27. char    *argv[];
  28. {
  29.     register int    c;
  30.     register int    f;
  31.     register int    n;
  32.     register int    mflag;
  33.     char        bname[NBUFN];
  34.  
  35.     strcpy(bname, "main");            /* Get buffer name.    */
  36.     if (argc > 1)
  37.         makename(bname, argv[1]);
  38.     vtinit();                /* Virtual terminal.    */
  39.     edinit(bname);                /* Buffers, windows.    */
  40.     keymapinit();                /* Symbols, bindings.    */
  41.     if (argc > 1) {
  42.         update();
  43.         readin(argv[1]);
  44.     }
  45.     lastflag = 0;                /* Fake last flags.    */
  46. loop:
  47.     update();                /* Fix up the screen.    */
  48.     c = getkey();
  49.     if (epresf != FALSE) {
  50.         eerase();
  51.         update();
  52.     }
  53.     f = FALSE;
  54.     n = 1;
  55.     if (c == (KCTRL|'U')) {            /* ^U, start argument.    */
  56.         f = TRUE;
  57.         n = 4;
  58.         while ((c=getkey()) == (KCTRL|'U'))
  59.             n *= 4;
  60.         if ((c>='0' && c<='9') || c=='-') {
  61.             if (c == '-') {
  62.                 n = 0;
  63.                 mflag = TRUE;
  64.             } else {
  65.                 n = c - '0';
  66.                 mflag = FALSE;
  67.             }
  68.             while ((c=getkey())>='0' && c<='9')
  69.                 n = 10*n + c - '0';
  70.             if (mflag != FALSE)
  71.                 n = -n;
  72.         }
  73.     }
  74.     if (kbdmip != NULL) {            /* Save macro strokes.    */
  75.         if (c!=(KCTLX|')') && kbdmip>&kbdm[NKBDM-6]) {
  76.             ctrlg(FALSE, 0, KRANDOM);
  77.             goto loop;
  78.         }
  79.         if (f != FALSE) {
  80.             *kbdmip++ = (KCTRL|'U');
  81.             *kbdmip++ = n;
  82.         }
  83.         *kbdmip++ = c;
  84.     }
  85.     execute(c, f, n);            /* Do it.        */
  86.     goto loop;
  87. }
  88.  
  89. /*
  90.  * Command execution. Look up the binding in the the
  91.  * binding array, and do what it says. Return a very bad status
  92.  * if there is no binding, or if the symbol has a type that
  93.  * is not usable (there is no way to get this into a symbol table
  94.  * entry now). Also fiddle with the flags.
  95.  */
  96. execute(c, f, n)
  97. {
  98.     register SYMBOL    *sp;
  99.     register int    status;
  100.  
  101.     if ((sp=binding[c]) != NULL) {
  102.         thisflag = 0;
  103.         status = (*sp->s_funcp)(f, n, c);
  104.         lastflag = thisflag;
  105.         return (status);
  106.     }
  107.     lastflag = 0;
  108.     return (ABORT);
  109. }
  110.  
  111. /*
  112.  * Initialize all of the buffers
  113.  * and windows. The buffer name is passed down as
  114.  * an argument, because the main routine may have been
  115.  * told to read in a file by default, and we want the
  116.  * buffer name to be right.
  117.  */
  118. edinit(bname)
  119. char    bname[];
  120. {
  121.     register BUFFER    *bp;
  122.     register WINDOW    *wp;
  123.  
  124.     bp = bfind(bname, TRUE);        /* Text buffer.        */
  125.     blistp = bcreate("");            /* Special list buffer.    */
  126.     wp = (WINDOW *) malloc(sizeof(WINDOW));    /* Initial window.    */
  127.     if (bp==NULL || wp==NULL || blistp==NULL)
  128.         abort();
  129.     curbp  = bp;                /* Current ones.    */
  130.     wheadp = wp;
  131.     curwp  = wp;
  132.     wp->w_wndp  = NULL;            /* Initialize window.    */
  133.     wp->w_bufp  = bp;
  134.     bp->b_nwnd  = 1;            /* Displayed.        */
  135.     wp->w_linep = bp->b_linep;
  136.     wp->w_dotp  = bp->b_linep;
  137.     wp->w_doto  = 0;
  138.     wp->w_markp = NULL;
  139.     wp->w_marko = 0;
  140.     wp->w_toprow = 0;
  141.     wp->w_ntrows = nrow-2;            /* 2 = mode, echo.    */
  142.     wp->w_force = 0;
  143.     wp->w_flag  = WFMODE|WFHARD;        /* Full.        */
  144. }
  145.     
  146. /*
  147.  * Fancy quit command, as implemented
  148.  * by Jeff. If the current buffer has changed
  149.  * do a write current buffer. Otherwise run a command
  150.  * interpreter in a subjob. Two of these will get you
  151.  * out. Bound to "C-Z".
  152.  */
  153. jeffexit(f, n, k)
  154. {
  155.     if ((curbp->b_flag&BFCHG) != 0)        /* Changed.        */
  156.         return (filesave(f, n, KRANDOM));
  157.     return (spawncli(f, n, KRANDOM));    /* Suspend.        */
  158. }
  159.  
  160. /*
  161.  * Quit command. If an argument, always
  162.  * quit. Otherwise confirm if a buffer has been
  163.  * changed and not written out. Normally bound
  164.  * to "C-X C-C".
  165.  */
  166. quit(f, n, k)
  167. {
  168.     register int    s;
  169.  
  170.     if (f != FALSE                /* Argument forces it.    */
  171.     || anycb() == FALSE            /* All buffers clean.    */
  172.     || (s=eyesno("Quit")) == TRUE) {    /* User says it's OK.    */
  173.         vttidy();
  174.         exit(GOOD);
  175.     }
  176.     return (s);
  177. }
  178.  
  179. /*
  180.  * Begin a keyboard macro.
  181.  * Error if not at the top level
  182.  * in keyboard processing. Set up
  183.  * variables and return.
  184.  */
  185. ctlxlp(f, n, k)
  186. {
  187.     if (kbdmip!=NULL || kbdmop!=NULL) {
  188.         eprintf("Not now");
  189.         return (FALSE);
  190.     }
  191.     eprintf("[Start macro]");
  192.     kbdmip = &kbdm[0];
  193.     return (TRUE);
  194. }
  195.  
  196. /*
  197.  * End keyboard macro. Check for
  198.  * the same limit conditions as the
  199.  * above routine. Set up the variables
  200.  * and return to the caller.
  201.  */
  202. ctlxrp(f, n, k)
  203. {
  204.     if (kbdmip == NULL) {
  205.         eprintf("Not now");
  206.         return (FALSE);
  207.     }
  208.     eprintf("[End macro]");
  209.     kbdmip = NULL;
  210.     return (TRUE);
  211. }
  212.  
  213. /*
  214.  * Execute a macro.
  215.  * The command argument is the
  216.  * number of times to loop. Quit as
  217.  * soon as a command gets an error.
  218.  * Return TRUE if all ok, else
  219.  * FALSE.
  220.  */
  221. ctlxe(f, n, k)
  222. {
  223.     register int    c;
  224.     register int    af;
  225.     register int    an;
  226.     register int    s;
  227.  
  228.     if (kbdmip!=NULL || kbdmop!=NULL) {
  229.         eprintf("Not now");
  230.         return (FALSE);
  231.     }
  232.     if (n <= 0) 
  233.         return (TRUE);
  234.     do {
  235.         kbdmop = &kbdm[0];
  236.         do {
  237.             af = FALSE;
  238.             an = 1;
  239.             if ((c = *kbdmop++) == (KCTRL|'U')) {
  240.                 af = TRUE;
  241.                 an = *kbdmop++;
  242.                 c  = *kbdmop++;
  243.             }
  244.             s = TRUE;
  245.         } while (c!=(KCTLX|')') && (s=execute(c, af, an))==TRUE);
  246.         kbdmop = NULL;
  247.     } while (s==TRUE && --n);
  248.     return (s);
  249. }
  250.  
  251. /*
  252.  * Abort.
  253.  * Beep the beeper.
  254.  * Kill off any keyboard macro,
  255.  * etc., that is in progress.
  256.  * Sometimes called as a routine,
  257.  * to do general aborting of
  258.  * stuff.
  259.  */
  260. ctrlg(f, n, k)
  261. {
  262.     ttbeep();
  263.     if (kbdmip != NULL) {
  264.         kbdm[0] = (KCTLX|')');
  265.         kbdmip  = NULL;
  266.     }
  267.     return (ABORT);
  268. }
  269.  
  270. /*
  271.  * Display the version. All this does
  272.  * is copy the text in the external "version" array into
  273.  * the message system, and call the message reading code.
  274.  * Don't call display if there is an argument.
  275.  */
  276. showversion(f, n, k)
  277. {
  278.     register char    **cpp;
  279.     register char    *cp;
  280.  
  281.     cpp = &version[0];
  282.     while ((cp = *cpp++) != NULL) {
  283.         if (writemsg(cp) == FALSE)
  284.             return (FALSE);
  285.     }
  286.     if (f != FALSE)                /* No display if arg.    */
  287.         return (TRUE);
  288.     return (readmsg());
  289. }
  290.